#ifndef SERVEROPERATION_H
#define SERVEROPERATION_H
#include <QRunnable>
#include "tcpserver.h"
#include "requestcodec.h"
#include "rsacrypto.h"
#include "seckeyshm.h"
#include "dboperation.h"
#include "respondcodec.h"

// 用于和客户端建立连接的类
// 多重继承
class AcceptConnect : public QObject, public QRunnable
{
    Q_OBJECT
public:
    AcceptConnect();
    ~AcceptConnect();
    void run();

    // 终止run()函数的内部循环
    void stop();

signals:
    void showMsg(QString msg);

private:
    bool m_stop = false;
    TcpServer* m_server;
    SeckeyShm *m_shm;
};

// 用于和客户端通信的类
// 通信的类对象和主窗口对象没有任何关联, 没有办法直接进行数据的传递
// 可以通过间接的方式传递数据: 当前对象 -> AcceptConnect对象中 -> 窗口对象
class Communication : public QObject, public QRunnable
{
    Q_OBJECT
public:
    enum CmdType{Consult, Verify, Logout, Login};
    enum KeyLen{L16=16, L24=24, L32=32};
    Communication(TcpSocket* tcp, SeckeyShm* shm);
    ~Communication();

    // 秘钥协商
    void seckeyConsult(RequestInfo* info);

    // 秘钥校验
    void seckeyVerify(RequestInfo* info);

    // 秘钥注销
    void seckeyLogout(RequestInfo* info);

    // 登录
    void seckeyLogin(RequestInfo* info);

    void run();

signals:
    void showMsg(QString msg);

private:
    // 客户身份和签名的校验
    bool identifyVerify(RsaCrypto& rsa, RequestInfo* info);
    // 生成AES的秘钥
    QString generateAesKey(KeyLen len);
    // 序列化数据并且发送
    void sendSerializeMsg(RespondInfo* info, QString msg);

private:
    TcpSocket* m_tcp;
    SeckeyShm *m_shm;
    DBOperation *m_db;
};

#endif
